package com.gzhryc.jdbc.utils;

import com.gzhryc.jdbc.annotaion.*;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 对数据对象进行解析的相关方法
 * @author 张浩
 * @version 2017-8-7
 */
public class EntityUtils {

	public static Type getParameterizedType(Object obj){
		Type genType = obj.getClass().getGenericSuperclass();
		if(genType instanceof ParameterizedType){  
			//返回表示此类型实际类型参数的 Type 对象的数组。  
	        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
	        if(params.length > 0) { 
	        	return params[0];
	        }
	    }
		return null;
	}
	
	public static<T> Field getIdField(Class<T> clazz){
		Field[] fields = ClassTools.getDeclaredFields(clazz);
		for(Field field : fields){
			if(field.getAnnotation(Id.class) != null){
				field.setAccessible(true);
				return field;
			}
		}
		return null;
	}
	
	public static<T> Field getField(Class<T> clazz,String fieldName){
		Field[] fields = ClassTools.getDeclaredFields(clazz);
		for(Field field : fields){
			if(field.getName().equals(fieldName)) {
				return field;
			}
		}
		return null;
	}
	
	public static<T> String getTableName(Class<T> clazz){
		String tableName = null;
		Table table = clazz.getAnnotation(Table.class);
		if(table != null) {
			if(StringUtils.isNotBlank(table.name())){
				tableName = table.name();
			}else {
				tableName = clazz.getSimpleName();
			}
		}else {
			Class<?> superclass = clazz.getSuperclass();
			if(!superclass.equals(Object.class)){
				tableName = getTableName(superclass);
			}
		}
		return tableName;
	}
	
	public static<T> String getViewName(Class<T> clazz){
		String viewName = null;
		View view = clazz.getAnnotation(View.class);
		if(view != null) {
			if(StringUtils.isNotBlank(view.name())){
				viewName = view.name();
			}else {
				viewName = clazz.getSimpleName();
			}
		}else {
			Class<?> superclass = clazz.getSuperclass();
			if(!superclass.equals(Object.class)){
				viewName = getViewName(superclass);
			}
		}
		return viewName;
	}
	
	public static<T> String getName(Class<T> clazz){
		String name = getTableName(clazz);
		if(StringUtils.isBlank(name)) {
			name = getViewName(clazz);
		}
		if(StringUtils.isBlank(name)) {
			name = clazz.getSimpleName();
		}
		return name;
	}
	
	public static String getName(Field field,Column column){
		if(column != null && StringUtils.isNotBlank(column.name())){
			return column.name();
		}else{
			return field.getName();
		}
	}
	
	public static String getName(Field field){
		Column column = field.getAnnotation(Column.class);
		return getName(field,column);
	}
	
	/**
	 * 获取表属性
	 * @param clazz
	 * @return
	 */
	public static<T> List<Field> findTableColumn(Class<T> clazz){
		List<Field> result = new ArrayList<Field>();
		Field[] fields = clazz.getDeclaredFields();
		
		for(int i=0;i<fields.length;i++){
			Field field = fields[i];
			if(Modifier.isFinal(field.getModifiers()) || Modifier.isStatic(field.getModifiers())){
				continue;
			}
			if(field.isAnnotationPresent(Column.class) || field.isAnnotationPresent(Id.class)){
				field.setAccessible(true);
				result.add(field);
			}
		}
		
		Class<?> superclass = clazz.getSuperclass();
		while(!superclass.equals(Object.class)){
			Field[] superClassFields = superclass.getDeclaredFields();
			for(int i=0;i<superClassFields.length;i++){
				Field field = superClassFields[i];
				if(Modifier.isFinal(field.getModifiers()) || Modifier.isStatic(field.getModifiers())){
					continue;
				}
				if(field.isAnnotationPresent(Column.class) || field.isAnnotationPresent(Id.class)){
					field.setAccessible(true);
					result.add(field);
				}
			}
			superclass = superclass.getSuperclass();
		}
		return result;
	}
	
	public static<T> Map<String,Field> findTableColumn2(Class<T> clazz,boolean isAllField){
		Map<String,Field> result = new HashMap<String,Field>();
		Field[] fields = clazz.getDeclaredFields();
		
		for(int i=0;i<fields.length;i++) {
			Field field = fields[i];
			if (Modifier.isFinal(field.getModifiers()) || Modifier.isStatic(field.getModifiers())) {
				continue;
			}
			if (isAllField) {
				field.setAccessible(true);
				//H2数据库字段全部大写，其它数据不限,所有默认所有数据库都大写
				result.put(getName(field).toUpperCase(), field);
			} else if (field.isAnnotationPresent(Column.class) || field.isAnnotationPresent(Id.class)) {
				field.setAccessible(true);
				//H2数据库字段全部大写，其它数据不限,所有默认所有数据库都大写
				result.put(getName(field).toUpperCase(), field);
			}
		}
		
		Class<?> superclass = clazz.getSuperclass();
		while(!superclass.equals(Object.class)){
			Field[] superClassFields = superclass.getDeclaredFields();
			for(int i=0;i<superClassFields.length;i++){
				Field field = superClassFields[i];
				if(Modifier.isFinal(field.getModifiers()) || Modifier.isStatic(field.getModifiers())){
					continue;
				}
				if(isAllField){
					field.setAccessible(true);
					//H2数据库字段全部大写，其它数据不限,所有默认所有数据库都大写
					result.put(getName(field).toUpperCase(),field);
				}else if(field.isAnnotationPresent(Column.class) || field.isAnnotationPresent(Id.class)){
					field.setAccessible(true);
					result.put(getName(field).toUpperCase(),field);
				}
			}
			superclass = superclass.getSuperclass();
		}
		return result;
	}
}
